/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.zjdt.epserver.servlet.util;

import com.zjdt.epserver.db.service4mysql.CargoServiceImpl;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.dusin.util.DateUtil;
import org.dusin.util.DownLoadUtils;
import org.dusin.util.TheUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 *
 * @author dusin
 */
@WebServlet(name = "DownloadAll", urlPatterns = {"/servlet/util/DownloadAll"})
public class DownloadAll extends HttpServlet {

    private CargoServiceImpl instance;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/json;charset=UTF-8");
        ServletOutputStream out =null;
        PrintWriter pw = null;
        ZipOutputStream zipOut = null;
        String msg = "";
        String jsonResult = "";
        try {
            ServletContext servletContext = request.getServletContext();
            ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
            instance = (CargoServiceImpl) context.getBean("cargoService");
            String companyCode = request.getParameter("companyCode");
            String factoryCode = request.getParameter("factoryCode");
            String dateFrom = request.getParameter("dateFrom");
            String dateTo = request.getParameter("dateTo");
            String key = request.getParameter("searchKey");
            int page;
            int rows;
            try {
                page = Integer.parseInt(request.getParameter("page"));
                rows = Integer.parseInt(request.getParameter("rows"));
            } catch (NumberFormatException nfe) {
                page = 1;
                rows = 20;
            }
            page = 1;
            rows = 10000;  //导出不需要分页，所有设置很大的值
            List<Map<String, Object>> cargos = instance.findAll(null,companyCode,factoryCode, dateFrom, dateTo, key, (page - 1) * rows, rows);
            List<File> files = new ArrayList<File>();
            File dir = new File("./webapps/EPServer/photo/");  //服务器用目录下载文件所在目录  
            //File dir = new File("../webapps/EPServer/photo/");  //本机用目录下载文件所在目录  
            String adir = dir.getCanonicalPath();
            //System.out.println(adir);
            for(Map<String,Object> map:cargos){
                String photoFileName = (String)map.get("frontPhoto");
                if(photoFileName!=null&&!photoFileName.trim().equals("")){
                    File f = new File(dir,photoFileName);
                    if(f.isFile()&&f.exists()){
                        files.add(f);
                    }
                }
                photoFileName = (String)map.get("sidePhoto");
                if(photoFileName!=null&&!photoFileName.trim().equals("")){
                    File f = new File(dir,photoFileName);
                    if(f.isFile()&&f.exists()){
                        files.add(f);
                    }
                }
                photoFileName = (String)map.get("licensePhoto");
                if(photoFileName!=null&&!photoFileName.trim().equals("")){
                    File f = new File(dir,photoFileName);
                    if(f.isFile()&&f.exists()){
                        files.add(f);
                    }
                }
                photoFileName = (String)map.get("paperPhoto");
                if(photoFileName!=null&&!photoFileName.trim().equals("")){
                    File f = new File(dir,photoFileName);
                    if(f.isFile()&&f.exists()){
                        files.add(f);
                    }
                }
            }                      
            String zipFilename = null;
            String timestamp = DateUtil.get(new Date(),"yyyyMMdd_HHmmss");
            String dataDirectoryStr = "d:/ep";            
            zipFilename = "photo" + timestamp + ".zip";
                      
            if (!dir.exists()) {
                msg = "照片目录不存在"+adir;
                throw new Exception(msg);
            }
            String uuid = UUID.randomUUID().toString();
            String tempZipFile = dataDirectoryStr + "/temp/" + uuid + ".zip";  //临时zip文件名
            String mimeType = servletContext.getMimeType(zipFilename);//获取文件的mime类型
            response.setHeader("content-type", mimeType);
            String agent = request.getHeader("user-agent");

            //2.使用工具类方法编码文件名即可
            zipFilename = DownLoadUtils.getFileName(agent, zipFilename);
            //3.2设置响应头打开方式 content-disposition      千万不能写错
            response.setHeader("content-disposition", "attachment;filename=" + zipFilename);
            byte[] buffer = new byte[1024 * 8];
            zipOut = new ZipOutputStream(new FileOutputStream(tempZipFile));            
            out = response.getOutputStream();
            //zipOut = new ZipOutputStream(out);  直接将内容输出到out，不知为何下载的文件不正确
            for (File f : files) {
                FileInputStream fis = new FileInputStream(f);
                zipOut.putNextEntry(new ZipEntry(f.getName()));
                int len;
                //读入需要下载的文件的内容，打包到zip文件
                while ((len = fis.read(buffer)) > 0) {
                    zipOut.write(buffer, 0, len);
                }
                zipOut.closeEntry();
                fis.close();
            }// 临时文件生成没有问题

            zipOut.close();
            zipOut = null;
            FileInputStream tempZipfis = new FileInputStream(tempZipFile);//输入流
            int len = 0;    //代表读到的字节的个数
            while ((len = tempZipfis.read(buffer)) != -1) {//把输入流中的字节读到缓冲区，并且把读到的个数赋值给len，如果没有读取到文件的末尾
                out.write(buffer, 0, len);//输出流不停的往外写，因为是字节流，所以不用刷新。这里掌握不充分，知识点都不记得了
            }
            tempZipfis.close();
            //删除临时文件
            File tempZip = new File(tempZipFile);
            tempZip.delete();
        } catch (Exception e) {
            e.printStackTrace();
            pw = response.getWriter();
            response.setContentType("text/json");
            jsonResult = TheUtil.getJsonResult(false, msg);
            pw.println(jsonResult);            
        } finally {
            if (pw != null) {
                pw.close();
            }
            if (out != null) {
                out.close();
            }
            if (zipOut != null) {
                zipOut.close();
            }
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
